package com.ruoyi.apiserver.controller;

import com.alibaba.fastjson2.JSON;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.ruoyi.apiserver.base.MhBaseController;
import com.ruoyi.apiserver.config.WxPayProperties;
import com.ruoyi.apiserver.domain.MhOrderDTO;
import com.ruoyi.apiserver.services.ReportGenerationProducerService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.JsApiOrderModel;
import com.ruoyi.common.utils.OrderNumberGenerator;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.members.domain.MhUser;
import com.ruoyi.members.service.IMhUserService;
import com.ruoyi.mhorders.domain.MhOrder;
import com.ruoyi.mhorders.service.IMhOrderService;
import com.ruoyi.test.domain.MhTest;
import com.ruoyi.test.service.IMhTestService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@Api(tags = "登录接口接口")
@RequestMapping("/api/pay")
@Slf4j
public class PayController extends MhBaseController {

    @Autowired
    WxPayProperties wxPayProperties;

    @Autowired
    private IMhOrderService mhOrderService;

    @Autowired
    private IMhTestService mhTestService;

    @Autowired
    private IMhUserService mhUserService;


    @Autowired
    private ReportGenerationProducerService reportGenerationProducerService;

    @PostMapping("/getPrice")
    public AjaxResult getPrice(@RequestBody MhOrderDTO dto) {

        MhOrderDTO order = new MhOrderDTO();
        String Body = "";
        switch (dto.getTestType()) {
            case "standard":
                order.setPrice(new BigDecimal("0.01"));
                Body = "MBTI 标准版";
                break;
            case "professional":
                order.setPrice(new BigDecimal("16.9"));
                Body = "MBTI 专业版";
                break;
            case "complete":
                order.setPrice(new BigDecimal("26.9"));
                Body = "MBTI 完整版";
                break;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("Body", Body);
        map.put("Prcie", order.getPrice());
        return AjaxResult.success("获取价格成功！", map);

    }

    @PostMapping("/createPay")
    public AjaxResult createUnifiedOrder(@RequestBody MhOrderDTO dto) throws UnknownHostException {
        if (dto.getTestType().equals("")) {
            return AjaxResult.error("当前类型为空！，创建失败！");
        }
        dto.setProductId(dto.getTestId());

        //获取用户信息
        MhUser mhUser = mhUserService.selectMhUserById(getUserId());

        if (mhUser == null) {

            return AjaxResult.error("用户获取为空！");
        }
        //获取当前IP
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ip = inetAddress.getHostAddress();

        //获取当前用户的
        //todo::当前为类型商品写死的。后期改为活动配置
        MhOrderDTO order = new MhOrderDTO();
        String Body = "";
        switch (dto.getTestType()) {
            case "standard":
                order.setPrice(new BigDecimal("0.01"));
                Body = "MBTI 标准版";
                break;
            case "professional":
                order.setPrice(new BigDecimal("16.9"));
                Body = "MBTI 专业版";
                break;
            case "complete":
                order.setPrice(new BigDecimal("26.9"));
                Body = "MBTI 完整版";
                break;
        }


        //生成订单号
        String OrderNO = OrderNumberGenerator.nextOrderNumber();
        order.setOrderNo(OrderNO);
        order.setUserId(getUserId());
        //价格
        String generateStr = WxPayKit.generateStr();
        BigDecimal money = order.getPrice();
        Map<String, String> params = JsApiOrderModel
                .builder()
                .appid(wxPayProperties.getAppId())
                .mch_id(wxPayProperties.getMchId())
                // 订单描述
                .nonce_str(generateStr)
                .body(Body)
                // 订单号
                .out_trade_no(order.getOrderNo())
                // 支付金额注意是以分为单位的
                .total_fee(String.valueOf((money.multiply(new BigDecimal("100"))).intValue()))
                //发起订单者ip
                .spbill_create_ip(ip)
                .notify_url(wxPayProperties.getNotifyUrl())
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(mhUser.getOpenid())
                .build()
                .createSign(wxPayProperties.getMchKey(), SignType.MD5);
        //进行数据加密封装
        String xmlResult = WxPayApi.pushOrder(false, params);
        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
        if (StringUtils.equals(resultMap.get("return_code"), "SUCCESS")) {
            String prepayId = resultMap.get("prepay_id");
            Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxPayProperties.getAppId(),
                    wxPayProperties.getMchKey(), SignType.MD5);
            //保存订单信息
            MhOrder mhOrder1 = new MhOrder();
            mhOrder1.setOrderNo(order.getOrderNo());
            mhOrder1.setOrderType(1L);
            mhOrder1.setUserId(getUserId());
            mhOrder1.setProductName(Body);
            mhOrder1.setProductId(dto.getProductId());
            mhOrder1.setProductQuantity(1L);
            mhOrder1.setTotalAmount(money);
            mhOrder1.setOrderStatus(1L);
            mhOrder1.setOutOrderNo(order.getOrderNo());
            mhOrder1.setProductId(dto.getProductId());
            mhOrder1.setCreateTime(new Date());
            mhOrderService.insertMhOrder(mhOrder1);
            // 微信浏览器中拿此参数调起支付
            return AjaxResult.success("创建订单成功", packageParams);

        } else {
            return AjaxResult.error(resultMap.get("return_msg"));
        }

    }

    @Anonymous
    @PostMapping("/payNotify")
    public Map<String, String> parseOrderNotifyResult(@RequestBody String xmlData) throws ParseException {
        Map<String, String> map = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        System.out.println("微信回调开始了");

        //这里我只进行了部分回调信息的保存，更多参数请查看微信支付官方api:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7&index=8
        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlData);
        System.out.println("微信回调开始了::" + xmlData);
        /*----------------------分割线，下面的是业务代码，根据自己业务进行修改--------------------------*/
        //订单成功业务处理
        if ("SUCCESS".equals(resultMap.get("result_code"))) {
            System.out.println(resultMap);
            log.info(resultMap.toString());
            //订单号
            String out_trade_no = resultMap.get("out_trade_no");
            //todo：：修改订单状态
            MhOrder mhOrder = mhOrderService.selectMhOrderByOrderNO(out_trade_no);
            if (mhOrder == null) {
                map.put("return_code", "FAIL");
                map.put("return_msg", "参数格式校验错误(订单信息不存在)");
                return map;
            }
            mhOrder.setOrderStatus(2L);

            mhOrder.setTransactionId(resultMap.get("transaction_id"));
            mhOrder.setPayTime(sdf.parse(resultMap.get("time_end")));
            int totalFee = Integer.parseInt(resultMap.get("total_fee"));
            double Rtotal = totalFee / 100.00D;
            mhOrder.setRealAmount(Rtotal + "");
            mhOrderService.updateMhOrder(mhOrder);

            //修改Test的值
            mhOrder.getProductId();
            //mhTest的状态值
            MhTest test = new MhTest();
            test.setId(mhOrder.getProductId());
            test.setTestHasmoreinfo(1L);
            mhTestService.updateMhTest(test);


            //todo：：创建消息队列
            // 发送报告生成请求到消息队列
            reportGenerationProducerService.sendReportGenerationRequest(out_trade_no, mhOrder.getUserId());

//            System.out.println("执行具体业务");
        } else {
            System.out.println(resultMap.get("return_msg"));
            log.info(resultMap.get("return_msg"));
        }
        /*----------------------分割线，业务结束--------------------------*/

        map.put("return_code", "SUCCESS");
        map.put("return_msg", "OK");
        return map;
    }
}